package com.ruoyi.common.utils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * map 工具类
 * 
 * @author QBT
 */
public class MapUtils {

	// 找出在map1中存在，但在map2中不存在的键值对
	public static <T> Map<String, T> findMissingKeys(Map<String, T> map1, Map<String, T> map2) {
		return map1.keySet().stream().filter(key -> !map2.containsKey(key))
				.collect(Collectors.toMap(Function.identity(), map1::get));
	}

	// 找出在两个Map中都存在，但是值发生了改变的键值对
	public static <T> Map<String, T> findUpdatedKeys(Map<String, T> map1, Map<String, T> map2) {
		Map<String, T> result = new HashMap<>();
		for (String key : map1.keySet()) {
			if (map2.containsKey(key) && !map2.get(key).equals(map1.get(key))) {
				result.put(key, map2.get(key));
			}
		}
		return result;
	}

	// 找出在map2中存在，但在map1中不存在的键值对
	public static <T> Map<String, T> findNewKeys(Map<String, T> map1, Map<String, T> map2) {
		return map2.keySet().stream().filter(key -> !map1.containsKey(key))
				.collect(Collectors.toMap(Function.identity(), map2::get));
	}

	/**
	 * 将 HashMap 中的键从下划线命名转换为驼峰命名，并去掉原来的键值
	 * @param <V> 值的类型
	 * @param map 原始的 HashMap
	 * @return
	 */
	public static <V> HashMap<String, V> convertKeysToCamelCaseInPlace(Map<String, V> map) {
		HashMap<String, V> newMap = new HashMap<>();
		Iterator<Map.Entry<String, V>> iterator = map.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, V> entry = iterator.next();
			String originalKey = entry.getKey();
			String camelCaseKey = toCamelCase(originalKey);
			newMap.put(camelCaseKey, entry.getValue());
		}
		return newMap;
	}

	/**
	 * 将下划线命名的字符串转换为驼峰命名
	 * @param input 下划线命名的字符串
	 * @return 驼峰命名的字符串
	 */
	private static String toCamelCase(String input) {
		input = input.toLowerCase(Locale.ROOT);
		StringBuilder result = new StringBuilder();
		boolean capitalizeNext = false;
		for (int i = 0; i < input.length(); i++) {
			char c = input.charAt(i);
			if (c == '_') {
				capitalizeNext = true;
			} else {
				if (capitalizeNext) {
					result.append(Character.toUpperCase(c));
					capitalizeNext = false;
				} else {
					result.append(c);
				}
			}
		}
		return result.toString();
	}

}
